import { DependencyContainer } from 'tsyringe'
import { Body, Query, ROOT, SERVER_CALL, getFilePath, parseScope, skerReq } from '@sker/core'
import { existsSync } from 'fs';
import { dirname } from 'path';
export interface Addon<T> {
    (params: any): Promise<T>;
}
export interface AddonHandler<T> {
    (addon: Addon<T>): Promise<T>;
}
export const useAddon = async <T>(injector: DependencyContainer, handler: AddonHandler<T>, path: string) => {
    const root = injector.resolve(ROOT)
    const childContainer = injector.createChildContainer()
    const [method, router] = path.split(':')
    const paths = router.split('/')
    const { scope, addon, platform, controller, action, d } = parseScope(paths, {}, {});
    const callAddon = async (params: any) => {
        childContainer.register(SERVER_CALL, { useValue: true })
        if (method.toLocaleLowerCase() === 'get') {
            childContainer.register(Query, { useValue: params })
            childContainer.register(Body, { useValue: {} })
        }
        if (method.toLocaleLowerCase() === 'post') {
            childContainer.register(Body, { useValue: params })
            childContainer.register(Query, { useValue: {} })
        }
        const filePath = getFilePath({
            root: root,
            scope: scope,
            addon: addon,
            platform: platform,
            controller: controller,
            action: action,
            d: d,
            method: method
        })
        if (filePath && existsSync(filePath)) {
            let pkg = skerReq([dirname(filePath)], childContainer)(filePath)
            if (typeof pkg === 'undefined') {
                return
            }
            const method = Reflect.get(pkg, d)
            if (method) {
                if (typeof method === 'function') {
                    return method(childContainer)
                } else {
                    pkg = method;
                }
            }
            const _action = Reflect.get(pkg, action)
            if (_action) {
                if (typeof _action === 'function') {
                    return _action(childContainer)
                } else {
                    pkg = _action;
                }
            }
            const _controller = Reflect.get(pkg, controller)
            if (_controller) {
                if (typeof _controller === 'function') {
                    return _controller(childContainer)
                } else {
                    pkg = _controller;
                }
            }
            const _default = Reflect.get(pkg, 'default')
            if (_default) {
                if (typeof _default === 'function') {
                    return _default(childContainer)
                } else {
                    pkg = _controller;
                }
            }
        }
    }
    const res = await handler(callAddon)
    return res;
}

export default useAddon;